package aspecto.aspect;

import geral.exception.SegurancaException;

import java.lang.reflect.Method;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import seguranca.helper.SegurancaManagerHelper;
import aspecto.annotation.Permissao;

public aspect PermissaoAspecto {

	private static String paginaErro = null;

	public PermissaoAspecto() {
		if (paginaErro == null)
			paginaErro = ((HttpServletRequest) FacesContext
					.getCurrentInstance().getExternalContext().getRequest())
					.getContextPath() + "/erro_permissao.faces";
	}

	pointcut servicePoints() : 
		execution(@Permissao * *.*());

	before() throws SegurancaException: servicePoints() {
		Boolean erroSeguranca = true;
		try {
			// pega metodo target
			Method m = thisJoinPoint.getThis().getClass()
					.getMethod(thisJoinPoint.getSignature().getName(), null);

			StackTraceElement[] stackTraceElement = Thread.currentThread().getStackTrace();
			Method callerMethod = null;
			
			for(StackTraceElement stack: stackTraceElement){
				try {
					callerMethod = Class.forName(stack.getClassName()).getMethod(stack.getMethodName(), null);
					if(callerMethod.isAnnotationPresent(Permissao.class) && !callerMethod.equals(m)){
						String role = callerMethod.getAnnotation(Permissao.class).role().name();
						if (SegurancaManagerHelper.temPermissao(role, null)) {
							erroSeguranca = false;
							break;
						}
						
					}
					
				}catch (Exception e) {
					
				}
			}
			if(erroSeguranca){
				String role = m.getAnnotation(Permissao.class).role().name();
				if (!SegurancaManagerHelper.temPermissao(role, null))
					throw new SegurancaException();
			}
		} catch (Exception e) {
			throw new SegurancaException();
		}
	}
}